from django.http import JsonResponse, HttpResponse
from django.views import View
from libs.yuntongxun.sms import CCP
from utils.logger import logger


# Create your views here.

class ImageCodeView(View):

    def get(self, request, uuid):
        logger.info(f"call ImageCodeView. get, uuid:{uuid}")

        # 生成图片验证码和图片二进制.
        from libs.captcha.captcha import captcha
        # 获取生成的文本 txt和二进制 img.
        txt, img = captcha.generate_captcha()
        # 进行redis链接.
        from django_redis import get_redis_connection
        redis_cli = get_redis_connection('code')
        # 设置验证码， 过期时间(秒)， 对应的验证码值.
        redis_cli.setex(uuid, 100, txt)

        # 返回图片二进制.
        # MIME 类型.

        return HttpResponse(img, content_type='image/jpeg')

        #return JsonResponse({'code':0, 'image':'bbbbb'})


"""
短信发送平台
: 容联云通讯短信平台. https://www.yuntongxun.com

https://doc.yuntongxun.com/pe/5a531a353b8496dd00dcdfe2
1. 注册.
2. 绑定测试账号
    "控制台-管理-号码管理-测试号码"
    
免费测试流程：注册 >> 绑定测试号 >> 开发测试

短信业务免费开发测试
1.注册
我们提供免费开发测试，【免费开发测试前，请先 注册 成为平台用户】。咨询在线客服


2.绑定测试号
免费开发测试需要在"控制台—管理—号码管理—测试号码"绑定 测试号码 。



3.开发测试
开发测试过程请参考 短信业务接口 及 Demo示例 / sdk参考（新版）示例。Java环境安装请参考"新版sdk"。


4.免费开发测试注意事项
    1.免费开发测试需要使用到"控制台首页"，开发者主账户相关信息，如主账号、应用ID等。
    
    2.免费开发测试使用的模板ID为1，具体内容：【云通讯】您的验证码是{1}，请于{2}分钟内正确输入。其中{1}和{2}为短信模板参数。
    
    3.测试成功后，即可申请短信模板并 正式使用 。


5.测试后正式使用注意事项
    1.将模板id参数改为您申请创建的模板id。
    
    2.将appid参数改为您创建模板归属应用的appid。
"""

"""
发送验证码逻辑
    前端:
        1. 用户输入手机号， 图形验证码.
            sms_codes/mobile/?image_code=knss&image_code_id=xxxx
    后端:
        请求: 请接收请求， 获取请求参数(路由， 手机号， 用户图形验证码和uuid
        业务逻辑: 验证参数， 验证图片验证码， 生成短信验证码， 保存验证码， 发送短信验证码.
        响应: 返回响应 {'code':0, 'errmsg':'ok}
    步骤:
        1. 获取请求参数.
        2. 验证参数.
        3. 验证图片验证码
        4. 生成短信验证码.
        5. 保存短信验证码.
        6. 发送短信验证码.
        7. 返回响应.
"""

class SmsCodeView(View):
    def get(self, request, mid):
        # 1. 获取请求参数.
        image_code = request.GET.get('image_code')
        uuid = request.GET.get('image_code_id')
        # 2. 验证参数.
        if not all([image_code, uuid]):
            return JsonResponse({'code': 400, 'errmsg': '参数补全'})
        # 3. 验证图片验证码
        # 3.1 链接redis.
        from django_redis import get_redis_connection
        redis_cli = get_redis_connection('code')
        # 3.2 读取redis数据.
        redis_image_code = redis_cli.get(uuid)
        if redis_image_code is None:
            return JsonResponse({'code': 400, 'errmsg': '图片验证码已过期'})
        # 3.3 对比验证码
        if redis_image_code.decode().lower() != image_code.lower():
            return JsonResponse({'code': 400, 'errmsg': '无效验证码'})
        # 提取表示.
        send_flag = redis_cli.get('send_flag_%s' % mid)
        if send_flag is not None:
            return JsonResponse({'code': 400, 'errmsg': '操作过于频繁. 请稍后再试'})
        # 4. 生成短信验证码.
        from random import randint
        sms_code = '%04d' % (randint(0, 9999))

        # 管道. 降低链接次数，提高运行效率.
        pipe = redis_cli.pipeline()
        pipe.setex(mid, 300, sms_code)
        pipe.setex('send_flag_%s' % mid, 60, 1)
        pipe.execute()

        # # 5. 保存短信验证码.
        # redis_cli.setex(mid, 300, sms_code)
        # # 添加一个标记，避免重复发送
        # redis_cli.setex('send_flag_%s' % mid, 60, 1)
        # # 6. 发送短信验证码.

        # 直接发送短信
        # CCP().send_template_sms(mid, [sms_code, 5], 1)

        # 用celery进行异步发送.
        from celery_tasks.sms.tasks import celery_send_sms_code
        celery_send_sms_code.delay(mid, sms_code)

        # 7. 返回响应.
        return JsonResponse({'code': 0, 'errmsg': 'ok'})


"""
生产者
消费者
队列 （中间人，经纪人)
celery(实现)
 
伪代码:
class Broker(object):
    broker_list = []

class Worker(object):
    def run(self, broker, func):
        if func in broker.broker_list:
            func()
        else:
            return 'error'

class Celery(object):
    def __init__(self):
        self.broker = Broker()
        self.worker = Worker()

    def add(self, func):
        self.broker.broker_list.append(func)

    def work(self, func):
        self.worker.run(self.broker, func)

def send_sms_code()
    print("send_sms_code")

app = Celery()
app.add(send_sms_code)
app.work(send_sms_code)

"""

